import base64
import datetime

from django.contrib.auth import get_user_model
from django.http import JsonResponse
from django.views import View
from rest_framework import serializers
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer

# 如果自定义了用户表，那么就要使用这个方法来获取用户模型
# 没有自定义的话可以使用以下方式加载用户模型:
# from django.contrib.auth.models import User
# 不过这种是万能的
User = get_user_model()

# 重写TokenObtainPairSerializer类的部分方法以实现自定义数据响应结构和payload内容

from django.contrib.auth import get_user_model
from rest_framework import status
from rest_framework.response import Response
from rest_framework_simplejwt.views import TokenViewBase, TokenObtainPairView
from captcha.models import CaptchaStore
from captcha.views import captcha_image


# from .serializers import MyTokenSerializer, RegisterSerializers
# User = get_user_model()
# 自定义的登陆视图
class MyTokenSerializer(TokenObtainPairSerializer):
    captchaKey = serializers.IntegerField(required=True)
    captchaValue = serializers.CharField(required=True)


    @classmethod
    def get_token(cls, user):
        """
        此方法往token的有效负载 payload 里面添加数据
        例如自定义了用户表结构，可以在这里面添加用户邮箱，头像图片地址，性别，年龄等可以公开的信息
        这部分放在token里面是可以被解析的，所以不要放比较私密的信息

        :param user: 用戶信息
        :return: token
        """
        token = super().get_token(user)
        # 添加个人信息
        token['name'] = user.username
        return token

    def validate(self, attrs):
        print(attrs)
        # attrs.update({'captchaKey': 1})
        # attrs.update({'captchaValue': '12'})
        """
        此方法为响应数据结构处理
        原有的响应数据结构无法满足需求，在这里重写结构如下：
        {
            "refresh": "xxxx.xxxxx.xxxxx",
            "access": "xxxx.xxxx.xxxx",
            "expire": Token有效期截止时间,
            "username": "用户名",
            "email": "邮箱"
        }

        :param attrs: 請求參數
        :return: 响应数据
        """
        # data是个字典
        # 其结构为：{'refresh': '用于刷新token的令牌', 'access': '用于身份验证的Token值'}
        captcha_code = CaptchaStore.objects.filter(id=attrs['captchaKey']).first()
        # print(type(captcha_code.response),captcha_code.response)
        # print(type(attrs['captchaValue']),attrs['captchaValue'])
        # print(captcha_code.response == attrs['captchaValue'])
        # print(captcha_code and (
        #         captcha_code.response == attrs['captchaValue'] or captcha_code.challenge == attrs['captchaValue']))
        if captcha_code and (
                captcha_code.response == attrs['captchaValue'] or captcha_code.challenge == attrs['captchaValue']):
            captcha_code and captcha_code.delete()
            data = super().validate(attrs)
            print(data)

            # 获取Token对象
            refresh = self.get_token(self.user)
            # 加个token的键，值和access键一样
            data['token'] = data['access']
            # 然后把access键干掉
            del data['access']
            # 令牌到期时间 时间戳转成年月日时分秒
            data['expire'] = datetime.datetime.fromtimestamp(refresh.access_token.payload['exp']).strftime(
                "%Y-%m-%d %H:%M:%S")
            # data['expire'] = refresh.access_token.payload['exp']   # 有效期
            # 用户名
            data['username'] = self.user.username
            # 邮箱
            data['email'] = self.user.email
            return data

        else:
            # captcha_code and captcha_code.delete()
            return {"code": 400, "msg": "ok", "data": {'message': '验证码错误'}}
class LoginView(TokenObtainPairView):
    serializer_class = MyTokenSerializer  # 使用刚刚编写的序列化类

    # post方法对应post请求，登陆时post请求在这里处理
    def post(self, request, *args, **kwargs):
        # 使用刚刚编写时序列化处理登陆验证及数据响应
        print(f'request.data{request.data}')
        serializer = self.get_serializer(data=request.data)
        try:
            serializer.is_valid(raise_exception=True)
        except Exception as e:
            raise ValueError(f'验证失败： {e}')

        return Response(serializer.validated_data, status=status.HTTP_200_OK)


class CaptchaView(View):
    """
    获取图片验证码
    """
    authentication_classes = []

    # @swagger_auto_schema(
    #     responses={
    #         '200': openapi.Response('获取成功')
    #     },
    #     security=[],
    #     operation_id='captcha-get',
    #     operation_description='验证码获取',
    # )
    def get(self, request):
        hashkey = CaptchaStore.generate_key()
        id = CaptchaStore.objects.filter(hashkey=hashkey).first().id
        imgage = captcha_image(request, hashkey)
        # 将图片转换为base64
        image_base = base64.b64encode(imgage.content)
        json_data = {"key": id, "image_base": "data:image/png;base64," + image_base.decode('utf-8')}
        result = {
            'code': 200,
            'data': json_data
        }
        return JsonResponse(data=result)
